import moment from 'moment'
import { forEach, merge } from 'lodash-es'
export default {
  data() {
    return {
      // 主键字段名
      primaryKey: 'id',
      // 请求接口基础路径
      baseApi: '/',
      // 新建接口
      createApi: '',
      // 更新接口
      updateApiPrefix: '',
      // label 默认布局样式
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      // form控件默认布局样式
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      // 存放数据
      model: {},
      // 标题
      title: '',
      // 当前组件状态对象
      state: {
        // 当前抽屉/模态框是否显示
        visible: false,
        // 当前表单提交按钮状态
        confirmSubmit: false,
        // 当前表单数据加载状态
        formDataLoading: false
      },
      // 分页数据
      pagination: {
        pageSize: 10,
        current: 1,
        total: 0,
        showQuickJumper: true,
        showTotal: (total, range) =>
          `当前显示 ${range[0]} - ${range[1]} 条/共 ${total} 条`,
        showSizeChanger: true,
        pageSizeOptions: ['10', '20', '30', '50', '100']
      },
      // 列表数据接口
      listApi: '',
      // 删除接口
      deleteApiPrefix: '',
      // 导出接口
      exportApi: '',
      // 自定义参数（不被查询表单重置和改变的参数）
      customQueryParam: {},
      // 与查询条件绑定的参数（会被查询表单重置和改变的参数）
      queryParam: {},
      // 高级搜索 展开/关闭
      advanced: false,
      // 列表数据
      data: [],

      // 数据
      detailData: {},
      // 当前form是否包含上传
      isUpload: false,

      tipName: '',
      // 标记加载状态
      loadingData: false,
      // 是否允许撤回删除
      allowCanceledDelete: false,
      /**
       * 所有文件的集合都放置与fileWrapper对象中，提交的时候会自动遍历
       * 格式如下：
       * fileWrapper: {
       *  singleImageList: [],
       *  multiImageList: [],
       *  singleFileList: [],
       *  multiFileList: []
       * }
       */
      fileWrapper: {},
      /**
       * uuid集合
       */
      fileUuidList: [],
      /**
       * 文件前缀
       */
      filePrefix: '',
      /**
       * 当前关联的对象名称
       */
      relObjType: '',
      selectedRowKeys: [],
      count: 1
    }
  },
  computed: {},
  methods: {
    moment,
    /**
     * 分页、排序、筛选变化时触发
     * @param pagination 分页
     * @param filters 排序
     * @param sorter 筛选
     */
    handleTableChange(pagination, filters, sorter) {
      this.queryParam.pageNum = pagination.current
      this.queryParam.pageSize = pagination.pageSize
      this.appendSorterParam(sorter)
      this.getList()
    },
    /**
     * 构建排序
     * @param sorter
     */
    appendSorterParam(sorter) {
      if (sorter && sorter.field) {
        const field = sorter.field
        const order = sorter.order === 'ascend' ? 'ASC' : 'DESC'
        const orderBy = `${field}:${order}`
        this.queryParam.orderBy = orderBy
      } else {
        this.queryParam.orderBy = undefined
      }
    },
    onSelectChange(selectedRowKeys) {
      console.log('selectedRowKeys changed: ', selectedRowKeys)
      this.selectedRowKeys = selectedRowKeys
    },
    /**
     * 切换展示更多搜索框
     */
    toggleAdvanced() {
      this.advanced = !this.advanced
    },
    /**
     * 搜索，查询第一页（默认查询按钮触发）
     */
    onSearch() {
      this.pagination.current = 1
      this.handleTableChange(this.pagination)
    },
    /**
     * 下载文件
     * @param res
     */
    downloadFile(res) {
      console.log(res)
    },
    getListRequest() {},

    /**
     * get请求获取列表
     * @returns {Promise<any>}
     */
    getList() {
      return new Promise((resolve, reject) => {
        this.loadingData = true
        // const
        this.getListRequest()
          .then(res => {
            console.log('get list response', res)
            this.loadingData = false
            if (res.retCode === '000000') {
              this.data = res.data.list
              this.afterLoadList(this.data)
              if (res.data) {
                this.pagination.pageSize = res.data.pageSize
                this.pagination.current = res.data.pageNum
                this.pagination.total = res.data.total
                  ? Number(res.data.total)
                  : 0
              }
              resolve(res)
            } else {
              this.$notification.error({
                message: '获取列表数据失败',
                description: res.msg
              })
              reject(res.msg)
            }
          })
          .catch(err => {
            this.loadingData = false
            this.$notification.error({
              message: '获取列表数据失败',
              description: err.message
            })
            reject(err)
          })
        // get(
        //   this.listApi ? this.listApi : `${this.baseApi}/list`,
        //   this.buildQueryParam()
        // )
        //   .then(res => {
        //     this.loadingData = false
        //     if (res.code === 0) {
        //       this.data = res.data
        //       this.afterLoadList(this.data)
        //       if (res.page) {
        //         this.pagination.pageSize = res.page.pageSize
        //         this.pagination.current = res.page.pageIndex
        //         this.pagination.total = res.page.totalCount
        //           ? Number(res.page.totalCount)
        //           : 0
        //       }
        //       resolve(this.data)
        //     } else {
        //       this.$notification.error({
        //         message: '获取列表数据失败',
        //         description: res.msg
        //       })
        //       reject(res.msg)
        //     }
        //   })
        //   .catch(err => {
        //     this.loadingData = false
        //     this.$notification.error({
        //       message: '获取列表数据失败',
        //       description: err.message
        //     })
        //     reject(err)
        //   })
      })
    },
    afterLoadList(data) {
      console.log('after load list', data)
    },
    /**
     * 构建查询参数
     */
    buildQueryParam() {
      this.dateRange2queryParam()
      // 转化包含moment的时间类型
      this.contentTransform(this.queryParam)
      let tempQueryParam = {}
      //   // 合并自定义查询参数
      merge(tempQueryParam, this.customQueryParam)
      // 合并搜索参数
      merge(tempQueryParam, this.queryParam)
      // 改造查询条件（用于列表页扩展）
      tempQueryParam = this.rebuildQuery(tempQueryParam)
      return tempQueryParam
    },
    /**
     * 重新构建查询条件 (接收已经定义的customQueryParam与queryParam的合并值)
     * @param query
     * @returns {*}
     */
    rebuildQuery(query) {
      return query
    },
    /**
     * 构建区间查询参数
     */
    dateRange2queryParam() {
      forEach(this.dateRangeQuery, (v, k) => {
        if (k && v && v.length === 2) {
          this.queryParam[`${k}Begin`] = v[0] ? v[0].format('YYYY-MM-DD') : ''
          this.queryParam[`${k}End`] = v[1] ? v[1].format('YYYY-MM-DD') : ''
        }
      })
    },
    /**
     * 处理查询参数中的moment数据 默认转化为YYYY-MM-DD
     * 如果需要单独处理属性，那么请传入transform对象，指定属性的转化类型
     * 示例：{createTime: 'YYYY-MM-DD'}
     * @param content 待转化内容
     * @param transform 需要转化的格式
     */
    contentTransform(content, transform = {}) {
      if (content) {
        for (const key in content) {
          const value = content[key]
          const format = transform[key] || 'YYYY-MM-DD'
          if (value instanceof Array) {
            // 如果类型是moment，那么进行转化
            if (value && value[0] instanceof moment) {
              const transformTime = []
              for (let i = 0; i < value.length; i++) {
                transformTime[i] = value[i].format(format)
              }
              content[key] = transformTime
            }
          } else if (value instanceof moment) {
            content[key] = value.format(format)
          }
        }
      }
      return content
    },
    /**
     * 重置
     */
    reset() {
      this.queryParam = {}
      this.dateRangeQuery = {}
      this.getList()
    },
    async open(data) {
      this.state.visible = true
      this.beforeOpen(data)
      this.detailData = data
      if (data) {
        // 没有id数据则认为是新建
        this.model = {}
        if (!this.title) {
          this.title = '新建'
        }

        this.afterOpen()
      } else {
        // 否则作为更新处理
        this.state.formDataLoading = true
        // this.tipName = data.name

        try {
          const res = await this.getList()
          console.log('res ', res)
          if (res.retCode === '000000') {
            this.model = res.data
            if (!this.title) {
              this.title = '更新'
            }

            this.state.visible = true
            this.state.formDataLoading = false
            this.afterOpen(data)
          } else {
            this.$notification.error({
              message: '获取表单数据失败，请重试',
              description: res.msg
            })
            this.close()
            return false
          }
        } catch (e) {
          this.$message.error('获取数据出错，请重试')
          this.close()
          return false
        }
      }
    },
    /**
     * 关闭表单
     */
    close() {
      this.state.visible = false
      this.state.formDataLoading = false
      this.model = {}
      this.__defaultFileWrapperKeys__()
      // this.form.resetFields()
      this.afterClose()
    },
    /**
     * 点击级联类型后，加载select数据
     */
    handleCascaderSelectNext(data, clearParams = []) {
      // 将级联已经选中的统一清理
      clearParams.forEach(param => delete this.queryParam[param])
      // 选中的数据初始化
      Object.assign(this.more, data)
      this.$forceUpdate()
    },
    /***
     * 提交前的验证流程
     * @returns {Promise<any>}
     */
    validate() {
      return new Promise((resolve, reject) => {
        this.form.validateFields((err, values) => {
          if (!err) {
            resolve(values)
          } else {
            this.state.confirmSubmit = false
            reject(err)
          }
        })
      })
    },
    /***
     * 提交前对数据的处理（在验证正确之后的处理）
     * @param values
     */
    async enhance(values) {
      console.log('enhance ', values)
    },
    /***
     * 新建记录的提交
     * @param values
     * @returns {Promise<string>}
     */
    async add(values) {
      //   const createApi = this.createApi ? this.createApi : '/'
      //   const res = await dibootApi.post(`${this.baseApi}${createApi}`, values)
      const res = await this.addRequest(values)
      if (res.retCode === '000000') {
        return {
          data: res.data,
          msg: '添加记录成功'
        }
      } else {
        throw new Error(res.retInfo)
      }
    },
    addRequest(values) {
      console.log('add request', values)
    },
    updateRequest(values) {
      console.log('update request', values)
    },
    /***
     * 更新记录的提交
     * @param values
     * @returns {Promise<string>}
     */
    async update(values) {
      //   const updateApiPrefix = this.updateApiPrefix ? this.updateApiPrefix : ''
      //   const res = await dibootApi.put(
      //     `${this.baseApi}${updateApiPrefix}/${this.model[this.primaryKey]}`,
      //     values
      //   )
      const res = await this.updateRequest(values)
      console.log(res)
      if (res.retCode === '000000') {
        return {
          data: res.data,
          msg: '更新记录成功'
        }
      } else {
        throw new Error(res.retInfo)
      }
    },
    /***
     * 表单提交事件
     * @returns {Promise<void>}
     */
    async onSubmit() {
      this.state.confirmSubmit = true
      try {
        const values = await this.validate()
        await this.enhance(values)
        let result = {}
        if (this.model[this.primaryKey]) {
          // 新增该记录
          result = await this.add(values)
        } else {
          // 更新该记录
          values[this.primaryKey] = this.model[this.primaryKey]
          result = await this.update(values)
        }

        // 执行提交成功后的一系列后续操作
        this.state.confirmSubmit = false
        this.submitSuccess(result)
      } catch (e) {
        // 执行一系列后续操作
        this.state.confirmSubmit = false
        this.submitFailed(e)
      }
    },
    /***
     * 提交成功之后的处理
     * @param msg
     */
    submitSuccess(result) {
      this.state.confirmSubmit = false
      this.$notification.success({
        message: '操作成功',
        duration: 1,
        description: result.msg
      })
      this.close()
      // this.form.resetFields()
      this.$emit('complete')
      this.$emit('changeKey', result.data)
    },
    /***
     * 提交失败之后的处理
     * @param e
     */
    submitFailed(e) {
      // 如果是字符串，直接提示
      let msg
      if (typeof e === 'string') {
        msg = e
      } else {
        msg = e.message || e.msg
      }

      // 如果还没有消息内容，则可能是校验错误信息，进行校验错误信息提取
      if (!msg && typeof e === 'object') {
        msg = this.validateErrorToMsg(e)
      }
      this.state.confirmSubmit = false
      this.$notification.error({
        message: '操作失败',
        description: msg
      })
    },
    validateErrorToMsg(err) {
      return err.message
    },
    // 解决带有下拉框组件在滚动时下拉框不随之滚动的问题
    getPopupContainer(trigger) {
      return trigger.parentElement
    },
    beforeOpen(data) {
      console.log('before', data)
    },
    /****
     * 打开表单之后的操作
     * @param id
     */
    afterOpen(data) {
      console.log('after', data)
    },
    afterClose() {},
    /**
     * 清除form内容
     */
    clearForm() {
      // this.form.resetFields()
    },
    /***
     * select选择框启用search功能后的过滤器
     * @param input
     * @param option
     * @returns {boolean}
     */
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text
          .toLowerCase()
          .indexOf(input.toLowerCase()) >= 0
      )
    },
    /**
     * 回显指定属性的图片文件
     * @param id 当前model的id
     * @param relObjField 字段名
     */
    echoImgFile(id, relObjField) {
      console.log(id, relObjField)
    },
    /**
     * 文件数据转化
     * @param data 相应的数据
     * @param isImage 是否是图片
     * @returns {{uid: ((function(): *)|*|(function(): *)), response: string, filePath: *, name: (*|string), status: string}}
     */
    fileFormatter(data, isImage) {
      const { uuid: uid, fileName: name, accessUrl } = data
      const file = {
        uid, // 文件唯一标识，建议设置为负数，防止和内部产生的 id 冲突
        name, // 文件名
        status: 'done', // 状态有：uploading done error removed
        response: '{"status": "success"}', // 服务端响应内容
        filePath: data.accessUrl
      }
      isImage &&
        Object.assign(file, {
          url: `${this.filePrefix}${accessUrl}/image`,
          thumbUrl: `${this.filePrefix}${accessUrl}/image`
        })
      return file
    },
    /**
     * 设置文件uuid
     * @private
     */
    __setFileUuidList__(values) {
      // 如果包含上传功能，那么设置uuid
      if (this.isUpload) {
        this.fileUuidList = []
        const fileWrapperKeys = Object.keys(this.fileWrapper)
        if (fileWrapperKeys.length > 0) {
          for (const fileWrapperKey of fileWrapperKeys) {
            const tempFileList = this.fileWrapper[fileWrapperKey]
            if (
              tempFileList &&
              tempFileList.length &&
              tempFileList.length > 0
            ) {
              this.fileUuidList.push(...tempFileList.map(item => item.uid))
            }
          }
          values['fileUuidList'] = this.fileUuidList
        }
      }
    },
    /**
     * 初始化fileWrapper
     * @private
     */
    __defaultFileWrapperKeys__() {
      const fileWrapperKeys = Object.keys(this.fileWrapper)
      if (fileWrapperKeys.length > 0) {
        for (const fileWrapperKey of fileWrapperKeys) {
          this.fileWrapper[fileWrapperKey] = []
        }
      } else {
        this.fileWrapper = {}
      }
      this.fileUuidList = []
    },
    /***
     * 批量删除
     * @returns {boolean}
     */
    batchRemove() {
      //   if (this.selectedRowKeys == null || this.selectedRowKeys.length === 0) {
      //     this.$message.error('请选择需要操作的行')
      //     return false
      //   }
      //   const _this = this
      //   this.$confirm({
      //     title: '您是否确认批量删除所选项？',
      //     onOk() {
      //       // 开始删除选中的行
      //       dibootApi
      //         .deleteBody(`${_this.baseApi}/batchDelete`, _this.selectedRowKeys)
      //         .then(res => {
      //           if (res.code === 0) {
      //             _this.$message.success(res.msg)
      //             _this.getList()
      //           } else {
      //             _this.$message.error(res.msg)
      //           }
      //         })
      //     }
      //   })
    },
    /**
     * 删除
     * @param id
     * @returns {Promise<any>}
     */
    remove(id) {
      console.log(id)
      //   return new Promise((resolve, reject) => {
      //     let _this = this
      //     _this.$confirm({
      //       title: '删除',
      //       content: `确定删除该数据吗？`,
      //       okText: '确定',
      //       okType: 'danger',
      //       cancelText: '取消',
      //       onOk() {
      //         const deleteApiPrefix = _this.deleteApiPrefix
      //           ? _this.deleteApiPrefix
      //           : ''
      //         dibootApi
      //           .delete(`${_this.baseApi}${deleteApiPrefix}/${id}`)
      //           .then(async res => {
      //             if (res.code === 0) {
      //               if (_this.allowCanceledDelete) {
      //                 _this.$message.success(h => {
      //                   return h('span', [
      //                     '当前数据删除成功',
      //                     h(
      //                       'a-button',
      //                       {
      //                         props: {
      //                           type: 'link'
      //                         },
      //                         on: {
      //                           click: event => {
      //                             _this.canceledDelete(id)
      //                           }
      //                         }
      //                       },
      //                       '撤回'
      //                     )
      //                   ])
      //                 })
      //               } else {
      //                 _this.$message.success('当前数据删除成功')
      //               }
      //               await _this.getList()
      //               resolve(res.data)
      //             } else {
      //               _this.$notification.error({
      //                 message: '删除失败',
      //                 description: res.msg,
      //                 duration: 3
      //               })
      //               // eslint-disable-next-line prefer-promise-reject-errors
      //               reject(res.msg)
      //             }
      //           })
      //           .catch(err => {
      //             _this.$notification.error({
      //               message: '删除失败',
      //               description: err.msg,
      //               duration: 3
      //             })
      //             reject(err.msg)
      //           })
      //       }
      //     })
      //   })
    },
    async canceledDelete(id) {
      console.log(id)
      //   const res = await dibootApi.post(`${this.baseApi}/cancelDeleted/${id}`)
      //   if (res.code === 0) {
      //     this.$message.destroy()
      //     this.$message.success('撤回成功')
      //     this.getList()
      //   } else {
      //     this.$message.error('撤回失败')
      //   }
    },
    /**
     * 导出数据至excel
     */
    exportData() {
      //   const exportApi = this.exportApi ? this.exportApi : '/excel/export'
      //   dibootApi
      //     .download(`${this.baseApi}${exportApi}`, this.buildQueryParam())
      //     .then(res => {
      //       if (res.filename) {
      //         this.downloadFile(res)
      //       } else {
      //         let decoder = new TextDecoder('utf-8')
      //         let result = JSON.parse(decoder.decode(new Uint8Array(res)))
      //         this.$message.error(result.msg)
      //       }
      //     })
    }
  },
  props: {
    width: {
      type: Number,
      default: () => {
        return 720
      }
    }
  }
}
